package Designattern.Day3.prototype;

import java.io.*;

/**
 * @author ：Yan Guang
 * @date ：Created in 2020/5/18 16:07
 * @description： 原型模式
 * clone（）克隆函数 (潜拷贝)
 * 只能拷贝基本变量，引用变量都拷贝不了
 *
 * 深拷贝：方法一：重写clone()方法
 * 如下：(假设引用一个pizz类的对象:private Pizz pizz)
 * Object sheep = null;
 * sheep=super.clone();//先把基本数据变量给拷贝一下
 * Pizz pizztype = (Pizz)sheep;//讲sheep由object转变为pizz类
 * pizztype.pizz = (Pizz)pizz.clone();//复制一下引用变量
 * return pizztype
 *
 * 方式二：极力推荐使用，而且很强势
 */
public class Sheep implements Cloneable,Serializable{

    private static final long serialVersionUID = 369285298572941L;
    private String name;
    private String age;

    public Sheep() {
        super();
    }

    public Sheep(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "sheep{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    @Override
    protected Sheep clone(){
        Sheep clone = null;
        try {
            clone = (Sheep) super.clone();//这里一定要用super就是object类当中的方法
        } catch (Exception e) {
            e.printStackTrace();
        }
        return clone;
    }

    //极力推荐使用
    // 将该对象序列化成流,因为写在流里的是对象的一个拷贝，而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
    public Sheep Deepclone(){
        ByteArrayInputStream bis=null;
        ByteArrayOutputStream bos=null;
        ObjectInputStream ois= null;
        ObjectOutputStream oos=null;
        try {
            //序列化  将字节存入对象流里面，然后写下对象流
            bos =new ByteArrayOutputStream();
            oos =new ObjectOutputStream(bos);
            oos.writeObject(this);
            //反序列化  将写下的流先返回字节，然后读出对象流
            bis=new ByteArrayInputStream(bos.toByteArray());
            ois=new ObjectInputStream(bis);
            Sheep sheep = (Sheep) ois.readObject();
            return sheep;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static void main(String[] args) {
        Sheep sheep = new Sheep("YG","30");
        Sheep clone = sheep.Deepclone();
        System.out.println(sheep+"\t"+clone);
    }
}
